/**
 * 数组在JS中也是一个"对象",也是引用类型
 * JS可以给数组指定一个字符串类型的下标
 * 此处这个"下标"更有应该理解为"属性",也就相当于"键值对"
 * 
 * JS数组是一个对象,对象是可以在运行时动态的新增和删除属性的.
 */
//本质上是在创建一个hello属性
var arr = [];
arr['hello'] = 'world';
// arr.hello = 'world';
console.log(arr.hello);

//一.数组初始化
//使用new关键字创建
// let arr = new Array();

// let arr=[];
// let arr2=[1,2,'haha',false];//保存的内容称之为元素
// console.log(arr);
// console.log(arr2);
// console.log(arr2[2]);

// //如果下标超出范围读取元素,则结果为undefined
// console.log(arr2[100]);
// //不要给数组名直接赋值,因为动态类型的关系,可以理解为本来是个数组类型的,
// //如果字符串赋值后,就变成字符串了
// arr2 = "变成字符串";
// console.log(arr2);

// //二.新增数组元素
// //1.通过修改length新增
// //相当于在末尾新增元素,新增元素的默认值为undefined
// var arr = [1,2,3,"盖亚"];
// arr.length = 6;
// console.log(arr);
// console.log(arr[4]);
// console.log(arr[5]);

// //2.通过下标新增
// //如果下标超出范围赋值元素,则会给指定位置插入新元素
// let arr = [];
// arr[2] = 10;
// console.log(arr);
// //0和1的元素未赋值,所以默认为undefined

// //3.使用push进行追加元素
// let arr = [];
// for(let i = 0;i < 5;i++){
//     arr.push(i);
// }
// console.log(arr);

// //4.删除数组中的元素
// var arr = [1,2,3,5];
// //表示从下标为2的位置开始删除,删除的元素为1个
// arr.splice(2,1);
// console.log(arr);


//三.函数
//函数(function)就是方法(method),方法就是函数

// 如果去咬文嚼字,
// function指的是一个独立的函数
// method指的是某个类/对象的成员函数

/*// 创建函数/函数声明/函数定义
function 函数名(形参列表) {
       函数体
       return 返回值; }
   // 函数调用
   函数名(实参列表)           // 不考虑返回值
   返回值 = 函数名(实参列表)  //考虑返回值
   */

//    function dio(){
//        console.log("ko no dio da!");
//    }
//    dio();

// // 实参和形参之间的个数可以不匹配. 但是实际开发一般要求形参和实参个数要匹配
// （1） 如果实参个数比形参个数多, 则多出的参数不参与函数运算
// sum(10, 20, 30);    // 30
// 2) 如果实参个数比形参个数少, 则此时多出来的形参值为 undefined
// sum(10);    // NaN, 相当于 num2 为 undefined.

// function sum(x,y){
//     return x+y;
// }
// var a = sum(10,20);
// var b = sum(10,20,30);
// var c = sum(10);
// console.log(a);
// console.log(b);
// console.log(c);

// //定义了一个匿名(没有函数名)的函数,把这个函数复制给另外一个变量,
// //此时就可以拿着这个变量来进行函数调用了
// let add = function (a,b,c,d){
//     a = a || 0;
//     b = b || 0;
//     c = c || 0;
//     d = d || 0;
//     return a + b + c + d;
// }
/**
 *  不定义函数名的函数,一般成为匿名函数,也叫做lambda表达式
 * java也有lambda表达式,也是为了表达类似的效果
 * 但还是受限于Java语法本身,函数不能独立
 * 因此Java的lambda严格来说不能算是一个匿名函数,而是相当于一个"函数式接口"的对象
 * 
 */

//四.作用域
/**
 * JS中的作用域
 * 和Java差距也比较大
 * 
 * 不同的定义变量方式,有区别
 * 
 * var定义的变量,没有块级作用域.
 * let定义的变量,有块级作用域,(代码块级别的,{}限制作用域)
 * 
 * 后边讨论的作用域,只是讨论let,var就不管了
 * 
 * JS里面的函数内部还能定义函数
 * 然后某个函数内尝试使用的变量就会沿着这个函数定义的嵌套关系,逐渐往上找,
 * 一直找到最顶层的全局作用域
 * 
 * Java中"匿名内部类"可以直接捕获到外部类的一些成员变量/局部变量
 */

//// 作用域链
// var num = 1;
// function test1() {
//     var num = 10;
//     function test2() {
//         var num = 20;
//         console.log(num);
//   }
//    test2();
// }
// test1();
// //20
//执行 console.log(num) 的时候, 会现在 test2 的局部作用域中查找 num. 如果没找到, 则继续去 test1 中
// 查找. 如果还没找到, 就去全局作用域查找.

// //五.对象
// let a = {};//空对象

// let student = {
//     name:'zhangsan',
//     age: 20,
//     height: 175,
//     sayHello: function(){
//         console.log('hello');
//     }
// };

// let s = student;
// console.log(s);
// console.log("年龄:"+s.age);
// //.调用
// s.sayHello();

// /**
//  * 对象创建出来之后,就可以使用对象的属性和方法
//  * 1)还是通过.进行成员访问操作
//  * 2)还可以通过[]类似于去下标的方式来访问
//  * 
//  * JS的对象都可以视为是object类型
//  * 就可以通过new Object来创建出一个object实例
//  */

// //使用函数对对象创建的过程进行封装
// function Cat(name,type){
//     this.name = name;
//     this.type = type;
//     this.miao = function(){
//         console.log('喵');
//     }
// }

// let cat1 = new Cat('咪咪','中华田园猫');
// let cat2 = new Cat('小黑','中华田园猫');
// let cat3 = new Cat('孙狗','带恶人');
// console.log(cat1);
// cat1.miao();